<!--
 * @description: 实体属性编辑
 * @fileName: EntityEditDialog.vue
 * @author: ssr
 * @date: 2023-01-05 15:05:03
 * @version: V1.0.0
! -->
<script setup lang="ts">
import type {
  ICampItem,
  IEntityDetail,
  IEntityInstance
} from "@@/apis/scn/type"
import type { IDrawCallback } from "@@/utils/CustomCesium/CustomCesium"
import { useScenarioStore } from "@/pinia/stores/scenario"
import {
  getCampList,
  getEntityDetail,
  getEntityInstanceById,
  updateEntityInstance
} from "@@/apis/scn"
import mitter from "@@/utils/mitter"
import { ElMessage } from "element-plus"
import { cloneDeep, isEmpty, isEqual } from "lodash-es"
import { reactive, ref, toRefs } from "vue"
import "@@/components/plugins/TypingValueBfModal"

const scenarioStore = useScenarioStore()
const formRef = ref()
const valuesTableRef = ref()

// 表单数据
const formState = ref({
  entityName: "",
  side: "",
  longitude: 0,
  latitude: 0,
  height: 0
})

// 弹窗控制
const visible = ref(false)
const confirmLoading = ref(false)
const defData = ref()
// 状态数据
const state = reactive<{
  tableLoading: boolean
  campList: ICampItem[]
  campMap: { [propName: string]: ICampItem }
  curId: string
}>({
  tableLoading: false,
  campList: [],
  curId: "",
  campMap: {}
})

const { campList } = toRefs(state)
const paramsList = ref([])

// 表单验证规则
const validValuesRules = ref({
  value: [
    { required: true, message: "值不能为空" }
  ]
})

function handleCloseTip(done: () => void) {
  if (isEqual(defData.value, {
    entityInfo: cloneDeep(formState.value),
    paramsList: cloneDeep(paramsList.value)
  })) {
    ElMessageBox.confirm("当前编辑未保存，是否确定关闭？").then(() => {
      done()
    })
  } else {
    done()
  }
}

/**
 * 显示编辑对话框
 */
async function handleShowDialog(id: string) {
  state.curId = id
  formState.value = {
    entityName: "",
    side: "",
    longitude: 0,
    latitude: 0,
    height: 0
  }

  // 查询实体信息
  await handleEntityInfo()

  const entityIndex = scenarioStore.getEntityInstanceById(id)
  const entity: IEntityInstance = scenarioStore.selectedEntityList[entityIndex]

  // 查询扩展参数
  entity && handleExtraParams(entity.id)

  // 查询阵营信息
  handleSearchCampList()

  defData.value = {
    entityInfo: cloneDeep(formState.value),
    paramsList: cloneDeep(paramsList.value)
  }

  visible.value = true
}

/**
 * 查询扩展参数
 */
function handleExtraParams(id: string) {
  getEntityDetail(id).then((res) => {
    if (res.code === 200) {
      try {
        paramsList.value = JSON.parse(res.data.extended)
      } catch (e) {
        console.error("解析扩展参数失败:", e)
        paramsList.value = []
      }
    }
  })
}

/**
 * 保存更新实体
 */
function handleConfirm() {
  formRef.value?.validate((valid: boolean) => {
    if (!valid) return

    confirmLoading.value = true

    const params = {
      id: state.curId,
      scnId: scenarioStore.scnId,
      basicInfo: {
        entityName: formState.value.entityName,
        side: formState.value.side,
        sideValue: state.campMap[formState.value.side]?.value,
        longitude: formState.value.longitude,
        latitude: formState.value.latitude,
        height: formState.value.height
      },
      extended: JSON.stringify(paramsList.value)
    }

    updateEntityInstance(params)
      .then(() => {
        ElMessage.success("更新成功")

        // 更新列表
        mitter.emit("updateSelectedEntity")

        // 根据id获取cesium Id
        const index = scenarioStore.getEntityInstanceById(state.curId)
        const instance = scenarioStore.selectedEntityList[index]
        const sideColor = state.campMap[formState.value.side]?.color

        scenarioStore.drawEntityManager?.updateById(
          instance.cesiumId,
          {
            entityName: formState.value.entityName,
            sideColor,
            longitude: formState.value.longitude,
            latitude: formState.value.latitude,
            height: formState.value.height
          },
          (res: IDrawCallback) => {
            let cloneIns = cloneDeep(instance)
            cloneIns.cesiumPosition = res.position
            cloneIns.basicInfo.entityName = formState.value.entityName
            cloneIns.basicInfo.side = formState.value.side
            cloneIns.basicInfo.sideColor = sideColor
            cloneIns.basicInfo.longitude = formState.value.longitude
            cloneIns.basicInfo.latitude = formState.value.latitude
            cloneIns.basicInfo.height = formState.value.height
            scenarioStore.selectedEntityList.splice(index, 1, cloneIns)
          }
        )
        visible.value = false
      })
      .finally(() => {
        confirmLoading.value = false
      })
  })
}

/**
 * 查询阵营列表
 */
function handleSearchCampList() {
  if (scenarioStore.scnId) {
    getCampList(scenarioStore.scnId).then(({ data }) => {
      state.campList = data
      state.campMap = {}
      state.campList.forEach((item) => {
        state.campMap[item.id] = item
      })
    })
  }
}

/**
 * 根据id查询实体信息
 */
function handleEntityInfo() {
  return new Promise((resolve) => {
    if (!isEmpty(state.curId)) {
      getEntityInstanceById(state.curId).then(({ data }) => {
        const entityInfo: IEntityDetail = data
        formState.value = {
          entityName: entityInfo.basicInfo.entityName,
          side: entityInfo.basicInfo.side,
          longitude: entityInfo.basicInfo.longitude,
          latitude: entityInfo.basicInfo.latitude,
          height: entityInfo.basicInfo.height
        }
        resolve(entityInfo)
      })
    } else {
      resolve(null)
    }
  })
}

/**
 * 取消操作
 */
function handleCancel() {
  visible.value = false
}

// 暴露方法给父组件
defineExpose({
  handleShowDialog
})
</script>

<template>
  <el-drawer
    v-model="visible"
    direction="rtl"
    size="1000"
    :before-close="handleCloseTip"
    :show-close="false"
    @close-auto-focus="handleCancel"
    @close="handleCancel"
  >
    <template #header>
      <div class="drawer-header">
        <h4>属性编辑</h4>
      </div>
    </template>
    <template #default>
      <div class="drawer-body-lock">
        <p class="title">
          基本属性：
        </p>
        <el-form
          ref="formRef"
          :model="formState"
          label-position="right"
          :label-width="100"
          autocomplete="off"
        >
          <el-row :gutter="24">
            <el-col :span="12">
              <el-form-item
                label="实体名称"
                prop="entityName"
                :rules="[{ required: true, message: '请输入实体名称!', trigger: 'blur' }]"
              >
                <el-input v-model="formState.entityName" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item
                label="所属方"
                prop="side"
                :rules="[{ required: true, message: '请选择所属方!', trigger: 'change' }]"
              >
                <el-select
                  v-model="formState.side"
                  placeholder="请选择"
                  style="width: 100%"
                >
                  <el-option
                    v-for="item in campList"
                    :key="item.id"
                    :label="item.label"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="经度" prop="longitude">
                <el-input-number
                  v-model="formState.longitude"
                  placeholder="经度"
                  :precision="6"
                  :controls="false"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="高度" prop="height">
                <el-input-number
                  v-model="formState.height"
                  placeholder="高度"
                  :precision="6"
                  :controls="false"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="纬度" prop="latitude">
                <el-input-number
                  v-model="formState.latitude"
                  placeholder="纬度"
                  :precision="6"
                  :controls="false"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>

        <p class="title">
          扩展属性：
        </p>
        <div class="drawertable-content">
          <vxe-table
            ref="valuesTableRef"
            class="drawer-table"
            height="auto"
            keep-source
            :edit-rules="validValuesRules"
            show-overflow="tooltip"
            show-header-overflow
            :data="paramsList"
            :edit-config="{ trigger: 'click', mode: 'row', showStatus: true }"
          >
            <vxe-table-column field="field.catalogId" :visible="false" />
            <vxe-table-column type="seq" title="序号" align="center" width="60" />
            <vxe-table-column field="field.code" title="参数名" />
            <vxe-table-column field="field.name" title="参数描述" />
            <vxe-table-column field="field.type" title="分类" formatter="formatType" />
            <vxe-table-column field="field.typeCode" title="数据类型" />
            <vxe-table-column
              field="value" title="值" width="300" formatter="formatValue"
              :cell-render="{ name: 'TypingValueBfModal' }"
            />
          </vxe-table>
        </div>
      </div>
    </template>

    <template #footer>
      <div class="dialog-footer">
        <el-button plain @click="handleCancel">
          取 消
        </el-button>
        <el-button :loading="confirmLoading" type="primary" @click="handleConfirm">
          确 定
        </el-button>
      </div>
    </template>
  </el-drawer>
</template>

<style lang="scss" scoped>
:deep(.el-input-number .el-input__inner) {
  text-align: left !important;
}

.title {
  font-weight: 500;
  margin-bottom: 16px;
  color: var(--el-text-color-primary);
}
</style>
